/*
 * UltimateCrabsPwn3r.java
 *
 * @Author Mouchicc < mourad94_4@hotmail.com >
 *
 * @Date 2009
 *
 * This script is free software. It may not be redistributed or sold without authors permission.
 *
 * Updates:
 * - v1.2 = A fix from here and there
 * 
 * 
 * Thread of Script: 
 * http://www.rsbot.org/vb/showthread.php?t=57981
 *
 * 
 */

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Map;

import javax.imageio.ImageIO;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSItem;
import com.speljohan.rsbot.script.wrappers.RSItemTile;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSTile;
import com.speljohan.rsbot.script.wrappers.RSTilePath;

@SuppressWarnings("unused")
public class UltimateCrabsPwn3r extends Script implements
		ServerMessageListener, PaintListener {

	BufferedImage UltimateSeries = null;
	long lvls = 0;
	long startTime = System.currentTimeMillis();
	int startLvl;
	int startExp;
	int stat;
	String skill;
	int[] CRAB_ROCK_MODE = { 1266, 1268 };
	int[] CRAB_NORMAL_MODE = { 1265, 1267 };
	public int itemIndex;
	public int ITWID1 = 0000;
	public int ITWID2 = 0000;
	public int[] ITWIDs;
	public int ITPID1 = 0000;
	public int[] ITPIDs;
	public int ITPID2 = 0000;
	public int[] potID;
	public String ITPN1 = null;
	String[] ITPNs;
	public String ITPN2 = null;
	public int[] charms = { 12158, 12159, 12160, 12163 };
	public int fightMode;
	public boolean doingspec = false;
	public long attacking;
	public boolean potion = false;
	public boolean charmpickup = false;
	public boolean takeSomeItem = false;
	int eatAT;
	int runEnergy = random(18, 60);
	public int count = 0;
	public int[] FoodID = { 1895, 1893, 1891, 4293, 2142, 291, 2140, 3228,
			9980, 7223, 6297, 6293, 6295, 6299, 7521, 9988, 7228, 2878, 7568,
			2343, 1861, 13433, 315, 325, 319, 3144, 347, 355, 333, 339, 351,
			329, 3381, 361, 379, 380, 10136, 5003, 379, 365, 373, 374, 7946,
			385, 397, 391, 3369, 3371, 3373, 2309, 2325, 2333, 2327, 2331,
			2323, 2335, 7178, 7180, 7188, 7190, 7198, 7200, 7208, 7210, 7218,
			7220, 2003, 2011, 2289, 2291, 2293, 2295, 2297, 2299, 2301, 2303,
			1891, 1893, 1895, 1897, 1898, 1899, 1900, 1901, 1902, 7072, 7062,
			7078, 7064, 7084, 7082, 7066, 7068, 1942, 6701, 6703, 7054, 6705,
			7056, 7060, 2130, 1985, 1993, 1989, 1978, 5763, 5765, 1913, 5747,
			1905, 5739, 1909, 5743, 1907, 1911, 5745, 2955, 5749, 5751, 5753,
			5755, 5757, 5759, 5761, 2084, 2034, 2048, 2036, 2217, 2213, 2205,
			2209, 2054, 2040, 2080, 2277, 2225, 2255, 2221, 2253, 2219, 2281,
			2227, 2223, 2191, 2233, 2092, 2032, 2074, 2030, 2281, 2235, 2064,
			2028, 2187, 2185, 2229, 6883, 1971, 4608, 1883, 1885 };

	RSTile[] PATH2 = new RSTile[] { new RSTile(2707, 3717),
			new RSTile(2708, 3708), new RSTile(2706, 3697),
			new RSTile(2705, 3690), new RSTile(2706, 3685) };

	RSTile[] PATH3 = reversePath(PATH2);

	@Override
	public String getName() {
		return "UltimateCrabsPwn3r";
	}

	@Override
	public double getVersion() {
		return 1.2;
	}

	@Override
	public String getAuthor() {
		return "Mouchicc";
	}

	@Override
	public String getScriptCategory() {
		return "Combat";
	}

	@Override
	public String getScriptDescription() {
		String html = "";
		html += "<html>";
		html += "<head>";
		html += "<style type=\"text/css\"> hr {color: white} p {margin-left: 20px}</style>";
		html += "</head>";
		html += "<body>";
		html += "<center>";
		html += "<b><font size=\"6\" color=\"red\">" + getName() + " v"
				+ getVersion() + " M" + "</font></b><br>";
		html += "<font size=\"3\" color=\"red\">Please start @ the eastern Crabs.<br></font>";
		html += "<center><table border=\"0\"><tr><td colspan=\"5\"><center><font size=6><b>== Options and Settings ==</b></font></center></td></tr><tr><td colspan=4><hr></td></tr><tbody><tr><td width=\"135\">";
		html += "<b>Use Special:</b></td><td width=\"140\"><center><input type=\"checkbox\" name=\"spec\" value=\"true\"></center></td><td width=\"135\"></b></center></td></tr>";
		html += "<b>Use Potions:</b></td><td width=\"140\"><center><input type=\"checkbox\" name=\"pot\" value=\"true\"></center></td><td width=\"135\"></b></center></td></tr>";
		html += "<b>Pick Charms:</b></td><td width=\"140\"><center><input type=\"checkbox\" name=\"charm\" value=\"true\"></center></td><td width=\"135\"></b></center></td></tr>";
		html += "<tr><td><b>Eat At:</b>&nbsp<input type=\"text\" name=\"eatt\" size=\"4\"</center></td></tr>";
		html += "<b>Attack Style:</b></td><td width=\"140\"><center><select name=\"skill\"><option>Strength<option>Attack<option>Defence<option>Rapid Ranged<option>Accurate Ranged<option>Longrange Ranged</select></center></td><td width=\"135\"></b></center></td></tr>";
		html += "<tr><td><b>Pick Item ID:</b></td><td colspan=\"3\"><center><b>Item ID 1:</b>&nbsp<input type=\"text\" name=\"ItemID1\" size=\"4\">&nbsp&nbsp<b>Item ID 2:</b>&nbsp<input type=\"text\" name=\"ItemID2\" size=\"4\"></center></td></tr>";
		html += "<tr><td><b>Pick Item Name:</b></td><td colspan=\"3\"><center><b>Item name 1:</b>&nbsp<input type=\"text\" name=\"ItemN1\" size=\"10\">&nbsp&nbsp<b>Item name 2:</b>&nbsp<input type=\"text\" name=\"ItemN2\" size=\"10\"></center></td></tr>";
		html += "<tr><td><b>Arrow/Knife Wield ID:</b></td><td colspan=\"3\"><center><b>Item ID 1:</b>&nbsp<input type=\"text\" name=\"ItemW1\" size=\"10\">&nbsp&nbsp<b>Item ID 2:</b>&nbsp<input type=\"text\" name=\"ItemW2\" size=\"10\"></center></td></tr>";
		html += "</center>";
		html += "</center></body>";
		html += "</html>";
		return (html);
	}

	@SuppressWarnings("deprecation")
	@Override
	public boolean onStart(Map<String, String> args) {
		Bot.getEventManager().addListener(PaintListener.class, this);
		Bot.getEventManager().addListener(ServerMessageListener.class, this);
		log("Credits to Killa for: Special and checking for running South");
		log("Credits to Drizzt for: Walk on Screen method");
		log("Credits to Alowaniak for: ItemIndex Method");
		log("Credits to Noobielul for: Paint basics");
		log("************************************************");
		log("********UltimateCrabsPwn3r V" + getVersion() + " started!********");
		log("*********Let's get some Experience**************");
		log("************************************************");
		if (args.get("charm") != null) {
			charmpickup = true;
		} else {
			charmpickup = false;
		}
		if (args.get("spec") != null) {
			doingspec = true;
		} else {
			doingspec = false;
		}
		if (args.get("pot") != null) {
			potion = true;
		} else {
			potion = false;
		}
		if (args.get("skill").equals("Attack")) {
			stat = STAT_ATTACK;
			skill = "Attack";
			fightMode = 0;
			potID = new int[] { 121, 122, 123, 124, 125, 126, 145, 146, 147,
					148, 149, 150, 2428, 2429, 2436, 2437, 11429, 11430, 11431,
					11432, 9739, 9740, 9741, 9742, 9743, 9744, 9745, 9746 };
		}
		if (args.get("skill").equals("Strength")) {
			stat = STAT_STRENGTH;
			skill = "Strength";
			fightMode = 1;
			potID = new int[] { 113, 114, 115, 116, 117, 118, 119, 120, 157,
					158, 159, 160, 161, 162, 2440, 2441, 11441, 11442, 11443,
					11444, 9739, 9740, 9741, 9742, 9743, 9744, 9745, 9746 };

		}
		if (args.get("skill").equals("Defence")) {
			stat = STAT_DEFENSE;
			skill = "Defence";
			fightMode = 3;
			potID = new int[] { 133, 134, 135, 136, 137, 138, 163, 164, 165,
					166, 167, 168, 2432, 2433, 2442, 2443, 11457, 11458, 11459,
					11460, 9739, 9740, 9741, 9742, 9743, 9744, 9745, 9746 };
		}
		if (args.get("skill").equals("Accurate Ranged")) {
			stat = STAT_RANGE;
			skill = "Ranged";
			fightMode = 0;
			potID = new int[] { 169, 170, 171, 172, 173, 174, 2444, 2445,
					11509, 11510, 11511, 11512 };
		}
		if (args.get("skill").equals("Rapid Ranged")) {
			stat = STAT_RANGE;
			skill = "Ranged";
			fightMode = 1;
			potID = new int[] { 169, 170, 171, 172, 173, 174, 2444, 2445,
					11509, 11510, 11511, 11512 };
		}
		if (args.get("skill").equals("Longrange Ranged")) {
			stat = STAT_RANGE;
			skill = "Ranged";
			fightMode = 3;
			potID = new int[] { 169, 170, 171, 172, 173, 174, 2444, 2445,
					11509, 11510, 11511, 11512 };
		}
		if (!args.get("eatt").equals("")) {
			eatAT = Integer.parseInt(args.get("eatt"));
		}
		if (!args.get("ItemID1").equals("")) {
			ITPID1 = Integer.parseInt(args.get("ItemID1"));
			takeSomeItem = true;
		}
		if (!args.get("ItemID2").equals("")) {
			ITPID2 = Integer.parseInt(args.get("ItemID2"));
			takeSomeItem = true;
		}
		if (!args.get("ItemN1").equals("")) {
			ITPN1 = args.get("ItemN1");
		}
		if (!args.get("ItemN2").equals("")) {
			ITPN2 = args.get("ItemN2");
		}
		if (!args.get("ItemW1").equals("")) {
			ITWID1 = Integer.parseInt(args.get("ItemW1"));
		}
		if (!args.get("ItemW2").equals("")) {
			ITWID2 = Integer.parseInt(args.get("ItemW2"));
		}
		ITPIDs = new int[] { ITPID1, ITPID2, };
		ITPNs = new String[] { ITPN1, ITPN2 };
		ITWIDs = new int[] { ITWID1, ITWID2 };
		try {
			URL url = new URL(
					"http://img35.imageshack.us/img35/4292/ultimateseries.png");
			UltimateSeries = ImageIO.read(url);
		} catch (IOException e) {
		}
		return true;
	}

	public void onFinish() {
		Bot.getEventManager().removeListener(PaintListener.class, this);
		Bot.getEventManager().removeListener(ServerMessageListener.class, this);
		log("Thanks for using the script!");
		log("XP per hour: "
				+ ((skills.getCurrentSkillExp(stat) - startExp) * (3600000D / (((double) System
						.currentTimeMillis() - (double) startTime)))));
		log("Levels Gained: " + (skills.getCurrentSkillLevel(stat) - startLvl));
		log("Experience Gained: "
				+ (skills.getCurrentSkillExp(stat) - startExp));
	}

	// Eat method
	void eat(final int id) {
		atInventoryItem(id, "Eat");
		wait(random(1500, 2500));
		return;
	}

	// Check on food method
	private void eat_check() {
		final RSItem food = getInventoryItemByID(FoodID);
		if (getInventoryCount(FoodID) >= 1) {
			eat(food.getID());
		} else {
			walkToSouth();
			log("No food and low HP, running away and stopping all scripts!!");
			wait(random(5000, 7000));
			if (!getMyPlayer().isInCombat()) {
				logout();
				stopAllScripts();
			}
			return;
		}
	}

	// Does eating
	void EATING() {
		final int php = skills.getCurrentSkillLevel(3);
		if (php <= eatAT) {
			eat_check();
		} else {
			wait(random(20, 30));
		}
	}

	// Gets ItemIndex
	public int getITPIDsIndex(int id) {
		for (int i = 0; i < ITPIDs.length; i++)
			if (ITPIDs[i] == id)
				return i;
		return -1;
	}

	// Gets location of where player is
	private boolean isThere() {
		return getMyPlayer().getLocation().getY() >= 3714;
	}

	// Gets location north
	private boolean southThere() {
		return getMyPlayer().getLocation().getY() <= 3681;
	}

	// West location
	private boolean westThere() {
		return getMyPlayer().getLocation().getX() <= 2694;
	}

	// Gets Special
	public int getSpec() {
		return getSetting(300);
	}

	// Gets if Special is Enabled
	public boolean specEnabled() {
		return (getSetting(301)) == 1;
	}

	// Does Special!
	public void doSpec() {
		if (getSpec() >= 1000 && !specEnabled() && doingspec == true) {
			openTab(Constants.TAB_ATTACK);
			clickMouse(645 + random(0, 4), 425 + random(0, 4), true);
			wait(350);
		}
		return;
	}

	// Does Walking to Crabs
	void Walking() {
		if (getNearestNPCByID(CRAB_ROCK_MODE).getLocation().getX() <= 2691) {
			wait(random(50, 150));
		} else {
			WalkSmart(getNearestNPCByID(CRAB_ROCK_MODE).getLocation());
			wait(random(50, 150));
		}
	}

	// Walks onScreen Option
	public boolean WalkSmart(final RSTile t2) {
		final Point p = tileToMinimap(t2);
		final RSTile t = new RSTile(t2.getX() + random(-1, 1), t2.getY());
		if (tileOnScreen(t)) {
			if (atTile(t, "Walk Here")) {
				while (getMyPlayer().isMoving()) {
					wait(random(200, 400));
				}
				return true;
			}
		}
		if (p.x == -1 || p.y == -1) {
			return false;
		}
		clickMouse(p, 2, 2, true);
		while (getMyPlayer().isMoving()) {
			wait(random(200, 400));
		}
		return true;
	}

	// Walk to North option
	public boolean walkToNorth() {
		final RSTile[] randomizedPath = randomizePath(PATH3, 2, 2);
		final RSTilePath path = new RSTilePath(randomizedPath, this);
		try {
			return path.walkToEnd();
		} catch (final InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	// Walk to South option
	public boolean walkToSouth() {
		final RSTile[] randomizedPath = randomizePath(PATH2, 2, 2);
		final RSTilePath path = new RSTilePath(randomizedPath, this);
		try {
			return path.walkToEnd();
		} catch (final InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}
	
	void check_crabbydead() {
		RSNPC deadfreecrabby = getNearestFreeNPCByID(CRAB_ROCK_MODE);
		if (distanceTo(deadfreecrabby) <= 1
				&& getMyPlayer().getAnimation() == -1
				&& getMyPlayer().getInteracting() == null) {
			walkToSouth();
			log("Walking South");
		}
	}

	@Override
	public int loop() {
		// Continious walking
		if (getMyPlayer().isMoving()) {
			return (random(0, 50));
		}

		// Sets Running
		if (!isRunning()) {
			if (getEnergy() >= runEnergy) {
				setRun(true);
			}
		}
		// Does Special and/or Eating if is in Combat
		if (getMyPlayer().isInCombat()) {
			doSpec();
			EATING();
			return random(50, 100);
		}

		// Takes Charms
		RSItemTile charmItems = getGroundItemByID(5, charms);
		if (charmItems != null && !getMyPlayer().isInCombat()
				&& distanceTo(charmItems) <= 2) {
			atTile(charmItems, "Take ");
			wait(random(300, 800));
			return random(50, 100);
		}

		// Takes Item
		RSItemTile someItem = getGroundItemByID(5, ITPIDs);
		if (someItem != null && !getMyPlayer().isInCombat()
				&& distanceTo(someItem) <= 2) {
			int itemIndex = getITPIDsIndex(someItem.getItem().getID());
			atTile(someItem, "Take " + ITPNs[itemIndex]);
			wait(random(300, 800));
			return random(50, 100);
		}

		// Wields Arrows/Knifes if you put in
		if (getInventoryCount(ITWIDs[0]) > 100) {
			atInventoryItem(ITWIDs[0], "Wield");
		}

		// Sets FightMode, Camera and Compass
		setFightMode(fightMode);

		// Drinks potion if Checked Yes
		if (potion
				&& skills.getCurrentSkillLevel(stat)
						- skills.getRealSkillLevel(stat) <= random(1, 2)) {
			clickInventoryArray(potID, "Drink");
			wait(random(1000, 2000));
		}

		// If doing nothing walking to Crabs
		RSNPC crabbyisalive = getNearestFreeNPCByID(CRAB_NORMAL_MODE);
		RSNPC crabbyisdead = getNearestFreeNPCByID(CRAB_ROCK_MODE);
		if (crabbyisdead != null && getMyPlayer().getAnimation() == -1
				&& getMyPlayer().getInteracting() == null) {
			if (distanceTo(crabbyisdead) > 1 && !getMyPlayer().isMoving()
					&& !getMyPlayer().isInCombat()) {
				Walking();
				wait(random(750, 1000));
			}
		}

		// If Crabs aren't aggressive walking south
		RSNPC alivefreecrabby = getNearestFreeNPCByID(CRAB_NORMAL_MODE);
		RSNPC deadfreecrabby = getNearestFreeNPCByID(CRAB_ROCK_MODE);
		if (distanceTo(deadfreecrabby) <= 1) {
			check_crabbydead();
			wait(random(750, 1000));
		}

		// Runs back North
		if (getMyPlayer().getLocation().getY() <= 3675) {
			walkToNorth();
			log("Running North");
		}

		// Walks to Center if Player is at west Crabs
		if (getMyPlayer().getLocation().getX() <= 2696
				&& !getMyPlayer().isInCombat() && !getMyPlayer().isMoving()
				&& getGroundItemByID(5, charms) == null
				&& getGroundItemByID(5, ITPIDs) == null) {
			walkToNorth();
			log("Walking to Center");
		}

		// Attacks Crabs if they aren't interacting with other player
		if (getNearestNPCByID(CRAB_ROCK_MODE) != null
				&& distanceTo(getNearestNPCByID(CRAB_NORMAL_MODE)) <= 1
				&& !getNearestNPCByID(CRAB_ROCK_MODE).isInCombat()
				&& getMyPlayer().getInteracting() == null
				&& getNearestNPCByID(CRAB_ROCK_MODE).getInteracting() == null) {
			atNPC(getNearestFreeNPCByID(CRAB_NORMAL_MODE), "Attack");
		}
		return (random(50, 100));
	}

	// Paint of Script, Credits to Noobielul
	public void onRepaint(Graphics g) {
		if (isLoggedIn()) {
			if (startTime == 0)
				startTime = System.currentTimeMillis();

			if (startLvl <= 0 || startExp <= 0) {
				startLvl = skills.getCurrentSkillLevel(stat);
				startExp = skills.getCurrentSkillExp(stat);
			}

			long millis = System.currentTimeMillis() - startTime;
			long hours = millis / (1000 * 60 * 60);
			millis -= hours * (1000 * 60 * 60);
			long minutes = millis / (1000 * 60);
			millis -= minutes * (1000 * 60);
			long seconds = millis / 1000;

			int x = 0;
			int y = 20;
			g.setColor(new Color(0, 0, 0, 175));
			g.fillRoundRect(0, 20, 220, 100, 10, 10);
			g.fillRect(4, 319, 502, 17);
			g.setColor(Color.YELLOW);
			g.drawString("UltimateCrabsPwn3r - V" + getVersion(), x + 10,
					y += 15);
			g.setColor(Color.ORANGE);
			g.drawString("Bussy for " + hours + ":" + minutes + ":" + seconds,
					x + 10, y += 15);
			g.drawString("Current " + skill + " level : "
					+ skills.getRealSkillLevel(stat), x + 10, y += 15);
			g.drawString("Gained " + skill + " levels : " + lvls / 2, x + 10,
					y += 15);
			g.drawString("Gained " + skill + " exp : "
					+ (skills.getCurrentSkillExp(stat) - startExp), x + 10,
					y += 15);
			g
					.drawString(
							"Exp/hour : "
									+ (int) ((skills.getCurrentSkillExp(stat) - startExp) * (3600000D / (((double) System
											.currentTimeMillis() - (double) startTime)))),
							x + 10, y += 15);
			g.drawImage(UltimateSeries, 52, 360, null);
			g.setColor(Color.ORANGE);
			g.fillRect(5, 320, 5 * skills.getPercentToNextLevel(stat), 15);
			g.setColor(Color.WHITE);
			g.drawString(skills.getPercentToNextLevel(stat) + "%", 250, 331);
		}
	}

	// Method of clickInventoryArray
	private boolean clickInventoryArray(int[] itemID, String option) {
		try {
			if (getCurrentTab() != TAB_INVENTORY
					&& !RSInterface.getInterface(INTERFACE_BANK).isValid()
					&& !RSInterface.getInterface(INTERFACE_STORE).isValid()) {
				openTab(TAB_INVENTORY);
			}
			int[] items = getInventoryArray();
			java.util.List<Integer> possible = new ArrayList<Integer>();
			for (int X = 0; X < itemID.length; X++) {
				for (int i = 0; i < items.length; i++) {
					if (items[i] == itemID[X]) {
						possible.add(i);
					}
				}
			}
			if (possible.size() == 0) {
				return false;
			}
			final int idx = possible.get(random(0, possible.size()));
			final Point t = getInventoryItemPoint(idx);
			moveMouse(t, 5, 5);
			wait(random(100, 290));
			if (getMenuActions().get(0).equals(option)) {
				clickMouse(true);
				return true;
			} else {
				return atMenu(option);
			}
		} catch (final Exception e) {
			log("error clicking inventory");
			return false;
		}
	}

	// ServerMessage thingys
	public void serverMessageRecieved(ServerMessageEvent arg0) {
		String serverString = arg0.getMessage();
		if (serverString.contains("You've just advanced")) {
			lvls++;
			clickContinue();
		}
	}
}